package com.fc.mall.service.impl;

import com.fc.mall.dao.UmsWithdrawDao;
import com.fc.mall.dto.UmsWithdrawApproveParam;
import com.fc.mall.dto.UmsWithdrawCountStatus;
import com.fc.mall.dto.UmsWithdrawQueryParam;
import com.fc.mall.exception.ServiceException;
import com.fc.mall.mapper.SysPropertyConfigMapper;
import com.fc.mall.mapper.UmsMemberAccountChangeHistoryMapper;
import com.fc.mall.mapper.UmsMemberAccountMapper;
import com.fc.mall.mapper.UmsWithdrawMapper;
import com.fc.mall.model.*;
import com.fc.mall.service.SmsNoticeService;
import com.fc.mall.service.UmsWithdrawService;
import com.fc.mall.service.WxService;
import com.fc.mall.util.Constants;
import com.fc.mall.util.DateTimeHelper;
import com.fc.mall.util.Utils;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import ma.glasnost.orika.MapperFacade;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class UmsWithdrawServiceImpl implements UmsWithdrawService {

    @Autowired
    private UmsWithdrawDao umsWithdrawDao;

    @Autowired
    private UmsWithdrawMapper umsWithdrawMapper;

    @Autowired
    private WxService wxService;

    @Autowired
    private UmsMemberAccountMapper memberAccountMapper;

    @Autowired
    private SysPropertyConfigMapper sysPropertyConfigMapper;

    @Autowired
    private UmsMemberAccountChangeHistoryMapper memberAccountChangeHistoryMapper;

    @Autowired
    MapperFacade mapperFacade;

    @Autowired
    private SmsNoticeService noticeService;

    @Override
    public List<UmsWithdraw> getList(UmsWithdrawQueryParam queryParam, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        //名称模糊查询加密
        queryParam.setNickname(Utils.urlEncoderTransfer(queryParam.getNickname()));
        List<UmsWithdraw> umsWithdrawList = umsWithdrawDao.getList(queryParam);
        umsWithdrawList.forEach(v->{
            try {
                String nickname = StringUtils.isEmpty(v.getNickname()) ? "未授权" : v.getNickname();
                v.setNickname(URLDecoder.decode(nickname, "utf-8"));
            }catch (Exception e) {

            }
        });
        return umsWithdrawList;
    }

    @Override
    @Transactional
    public UmsWithdraw approve(Long withdrawId, UmsWithdrawApproveParam umsWithdrawApproveParam) {
        UmsWithdraw umsWithdraw = umsWithdrawMapper.selectByPrimaryKey(withdrawId);
        if (umsWithdraw == null) {
            throw new ServiceException("取现记录没找到");
        }
        mapperFacade.map(umsWithdrawApproveParam, umsWithdraw);
        handleWithdrawTransfer(umsWithdraw);
        return umsWithdraw;
    }

    /**
     * 提现不同状态数量统计
     * 0: 等待审核
     * 1：审核成功
     * 2：审核失败
     * 3：等待打款
     * 4：已打款
     * @return
     */
    @Override
    public UmsWithdrawCountStatus countStatus() {
        return umsWithdrawDao.countStatus();
    }


    private void handleWithdrawTransfer(UmsWithdraw umsWithdraw)
    {
        SysPropertyConfigExample example = new SysPropertyConfigExample();
        example.createCriteria().andCodeEqualTo("withdraw_configs_fee");
        List<SysPropertyConfig> configs =  sysPropertyConfigMapper.selectByExample(example);

        UmsMemberAccountExample accountExample = new UmsMemberAccountExample();
        accountExample.createCriteria().andMemberIdEqualTo(umsWithdraw.getMemberId());
        UmsMemberAccount memberAccount = memberAccountMapper.selectByExample(accountExample).get(0);
        Integer withDrawAmount = umsWithdraw.getAmount() * 100;
        try {
            // 驳回状态，将提现的钱返回到可用账户
            if(umsWithdraw.getStatus().equals(2))
            {
                throw new ServiceException(umsWithdraw.getReason());
            }
            //实现即时提现
            if(umsWithdraw.getStatus().equals(1))
            {
                wxService.transfer(umsWithdraw.getWx(), umsWithdraw.getAmountMoney(), "会员提现");
                withdrawNotice(umsWithdraw.getMemberId(), new BigDecimal(umsWithdraw.getAmountMoney()).setScale(2).toString());
            }
            UmsMemberAccountChangeHistory changeHistory = new UmsMemberAccountChangeHistory();
            changeHistory.setFromMemberId(umsWithdraw.getMemberId());
            changeHistory.setMemberId(umsWithdraw.getMemberId());
            changeHistory.setAmount(withDrawAmount.longValue());
            changeHistory.setAccountType(Constants.AccountType.WaitAccount.getValue());
            // 金额变更类型 1->购物佣金 2->提现奖励 3->购物消费(购物抵扣) 4->提现
            changeHistory.setType(0);
            changeHistory.setRemark(Constants.AccountChangeType.WithdrawDepositReward.getDesc());
            changeHistory.setCreateTime(new Date());
            memberAccountChangeHistoryMapper.insertSelective(changeHistory);

            Integer fee = Integer.valueOf(configs.get(0).getValue());
            umsWithdraw.setAmountFee(fee);
            umsWithdraw.setAmountMoney(umsWithdraw.getAmount().intValue() - fee);
            umsWithdraw.setApproveDate(new Date());
            umsWithdrawMapper.updateByPrimaryKeySelective(umsWithdraw);

            //手动动审核通过
            if(umsWithdraw.getStatus().intValue() == 3)
            {
                sendApprovalNotice(umsWithdraw.getMemberId(), umsWithdraw.getNickname(), "审核成功：提现：" + new BigDecimal(umsWithdraw.getAmountMoney()).setScale(2));
            }
            //已打款
            if(umsWithdraw.getStatus().intValue() == 4)
            {
                withdrawNotice(umsWithdraw.getMemberId(), new BigDecimal(umsWithdraw.getAmountMoney()).setScale(2).toString());
            }
        } catch (Exception e)
        {
            memberAccount.setAbleAmount(Long.valueOf(memberAccount.getAbleAmount().intValue() + withDrawAmount));
            memberAccountMapper.updateByPrimaryKeySelective(memberAccount);
            umsWithdraw.setReason(e.getMessage());
            umsWithdraw.setStatus(2);
            umsWithdraw.setApproveDate(new Date());
            umsWithdrawMapper.updateByPrimaryKeySelective(umsWithdraw);
            sendApprovalNotice(umsWithdraw.getMemberId(), umsWithdraw.getNickname(), "审核失败：" + e.getMessage());
            LOGGER.warn("Call UmsWithdrawServiceImpl.approve error", e);
        }

    }

    private void withdrawNotice(Long memberId, String amount)
    {
        JSONObject json = new JSONObject();
        json.put("memberId", memberId);
        json.put("amount", amount);
        json.put("applyDate", DateTimeHelper.getStringFromDate(new Date(), DateTimeHelper.PAYLOAD_DATEONLY));
        json.put("noticeType", 2);
        noticeService.sendNotice(json.toString());
    }
    private void sendApprovalNotice(Long memberId, String nickname, String status)
    {
        try {
            JSONObject json = new JSONObject();
            json.put("memberId", memberId);
            json.put("nickName", URLDecoder.decode(nickname, "utf-8"));
            json.put("type", "提现审核");
            json.put("status", status);
            json.put("approvalDate", DateTimeHelper.getStringFromDate(new Date(), DateTimeHelper.PAYLOAD_DATEONLY));
            json.put("noticeType", 3);
            noticeService.sendNotice(json.toString());
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

    }
}
